home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 11 / FM Towns Free Software Collection 11.iso / t_os / tool / artemis1 / src / rotate.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-10-11  |  4.3 KB  |  187 lines

  1. /*
  2.     ARTemis (Graphic Editor for FM-TOWNS)
  3.     (c) MATSUUCHI Ryosuke 1992,1993
  4.  
  5.     rotate.c
  6.  
  7.     「回転コピー」コマンド
  8. */
  9.  
  10. #include <stdio.h>
  11. #include <math.h>
  12. #include "ge.h"
  13. #include "imageman.h"
  14. #include "dispman.h"
  15. #include "mask.h"
  16.  
  17. static int input_angle(int ax0, int ay0, int *sin_, int *cos_)
  18. // 返値: 0=正常終了 -1=キャンセル
  19. {
  20.     void drawcsr(int msx,int msy)
  21.     {
  22.         int tx,ty;
  23.         tx = DMimage_getx(msx);
  24.         ty = DMimage_gety(msy);
  25.         MOFF;  EIMline(ax0,ay0,tx,ty,white,DrawXOR);  MON;
  26.     }
  27.     for(;;)
  28.     {
  29.         int prex,prey;
  30.         DMdispcsr(ms.x,ms.y);
  31.         drawcsr((prex=ms.x),(prey=ms.y));
  32.         do
  33.         {
  34.             ms_get(&ms);
  35.         } while (   ms.dx==0 && ms.dy==0 && ms.btn1==OFF && ms.btn2==OFF
  36.                  && key_chk()==0);
  37.         DMerasecsr();
  38.         drawcsr(prex,prey);            // 消去
  39.         scrollForCsr(1,1);
  40.         if (ms.btn1==OFFON)
  41.         {
  42.             int tx,ty;
  43.             tx=DMimage_getx(ms.x)-ax0, ty=DMimage_gety(ms.y)-ay0;
  44.             if (tx == 0 && ty == 0)
  45.                 *sin_ = 0, *cos_ = 0x8000;
  46.             else
  47.             {
  48.                 float len;
  49.                 len = sqrt((float)(tx*tx+ty*ty));
  50.                 *sin_ = -(int)(((float)ty * 65536) / len);
  51.                 *cos_ = (int)(((float)tx * 65536) / len);
  52.             }
  53.             return 0;
  54.         }
  55.         if (ms.btn2==OFFON)
  56.             return -1;
  57.     }
  58. }
  59.  
  60.  
  61. static int input_dest(int bx[],int by[],int sinn,int coss,int ax0,int ay0,
  62.                       int ax1,int ay1,int ax2,int ay2)
  63. {
  64.     sinn = -sinn;
  65.     void drawcsr(int msx,int msy)
  66.     {
  67.         int tx,ty;
  68.         tx = DMimage_getx(msx);
  69.         ty = DMimage_gety(msy);
  70.         MOFF;
  71.         EIMline(tx+bx[0],ty+by[0],tx+bx[1],ty+by[1],white,DrawXOR);
  72.         EIMline(tx+bx[0],ty+by[0],tx+bx[2],ty+by[2],white,DrawXOR);
  73.         EIMline(tx+bx[1],ty+by[1],tx+bx[3],ty+by[3],white,DrawXOR);
  74.         EIMline(tx+bx[2],ty+by[2],tx+bx[3],ty+by[3],white,DrawXOR);
  75.         MON;
  76.     }
  77.     area_drawbound();
  78.     MOFF;
  79.     EIMline(ax1,ay1,ax2,ay2,white,DrawXOR);
  80.     EIMline(ax1,ay2,ax2,ay1,white,DrawXOR);
  81.     MON;
  82.     for(;;)
  83.     {
  84.         int prex,prey;
  85.         DMdispcsr(ms.x,ms.y);
  86.         drawcsr((prex=ms.x),(prey=ms.y));
  87.         do
  88.         {
  89.             ms_get(&ms);
  90.         } while (   ms.dx==0 && ms.dy==0 && ms.btn1==OFF && ms.btn2==OFF
  91.                  && key_chk()==0);
  92.         DMerasecsr();
  93.         drawcsr(prex,prey);            // 消去
  94.         scrollForCsr(1,1);
  95.         if (ms.btn1==OFFON)
  96.         {
  97.             area_drawbound();
  98.             MOFF;
  99.             EIMline(ax1,ay1,ax2,ay2,white,DrawXOR);
  100.             EIMline(ax1,ay2,ax2,ay1,white,DrawXOR);
  101.             MON;
  102.             EIMbackup();
  103.             int tx,ty,bx1,bx2,by1,by2,bx0,by0,x,y;
  104.             tx=DMimage_getx(ms.x), ty=DMimage_gety(ms.y);
  105.             bx1 = _min(tx+bx[0],tx+bx[1],tx+bx[2],tx+bx[3]);
  106.             bx2 = _max(tx+bx[0],tx+bx[1],tx+bx[2],tx+bx[3]);
  107.             by1 = _min(ty+by[0],ty+by[1],ty+by[2],ty+by[3]);
  108.             by2 = _max(ty+by[0],ty+by[1],ty+by[2],ty+by[3]);
  109.             bx0 = (bx1+bx2)/2;
  110.             by0 = (by1+by2)/2;
  111.             bx1 = _max(0,bx1);
  112.             bx2 = _min(EIMgetxsize()-1,bx2);
  113.             by1 = _max(0,by1);
  114.             by2 = _min(EIMgetysize()-1,by2);
  115.             for (y=by1; y<=by2; y++)
  116.                 for (x=bx1; x<=bx2; x++)
  117.                 {
  118.                     int sx,sy;  // fixed-real
  119.                     sx = (ax0<<16) +  coss  *(x-bx0) + sinn*(y-by0);
  120.                     sy = (ay0<<16) + (-sinn)*(x-bx0) + coss*(y-by0);
  121.                     if (area_chkxy2(sx>>16,sy>>16))
  122.                         matte_pset(x,y,EIMpoint_back2(sx,sy),blkop);
  123.                 }
  124.             return 0;
  125.         }
  126.         if (ms.btn2==OFFON)
  127.         {
  128.             area_drawbound();
  129.             MOFF;
  130.             EIMline(ax1,ay1,ax2,ay2,white,DrawXOR);
  131.             EIMline(ax1,ay2,ax2,ay1,white,DrawXOR);
  132.             MON;
  133.             return -1;
  134.         }
  135.     }
  136. }
  137.  
  138.  
  139. static void commandRotate_sub(int meth)
  140. // meth : AREA_BOX / AREA_POLYGON
  141. {
  142.     for (;;)
  143.     {
  144. retry:
  145.         if (area_input(meth) != 0)
  146.             break;
  147.         EIMbackup();
  148.         int ax1,ay1,ax2,ay2,ax0,ay0;
  149.         int sinn,coss;  // fixed-real
  150.         area_getboundxy(&ax1,&ay1,&ax2,&ay2);
  151.         ax0 = (ax1 + ax2) / 2;
  152.         ay0 = (ay1 + ay2) / 2;
  153. angle:
  154.         area_drawbound();
  155.         MOFF;  EIMline(ax0,ay0,ax2,ay0,white,DrawXOR);  MON;
  156.         int r = input_angle(ax0,ay0,&sinn,&coss);
  157.         area_drawbound();
  158.         MOFF;  EIMline(ax0,ay0,ax2,ay0,white,DrawXOR);  MON;
  159.         if (r != 0)
  160.             goto retry;
  161.         int bx[4],by[4];
  162. #define    ROTXY(outn, x,y) \
  163.                 (bx[outn]=(( coss*(x))>>16) + ((sinn*(y))>>16), \
  164.                  by[outn]=((-sinn*(x))>>16) + ((coss*(y))>>16))
  165.         ROTXY(0,ax1-ax0,ay1-ay0);
  166.         ROTXY(1,ax2-ax0,ay1-ay0);
  167.         ROTXY(2,ax1-ax0,ay2-ay0);
  168.         ROTXY(3,ax2-ax0,ay2-ay0);
  169. #undef ROTXY
  170.         for (;;)
  171.         {
  172.             if (input_dest(bx,by,sinn,coss,ax0,ay0,ax1,ay1,ax2,ay2) != 0)
  173.                 goto angle;
  174.         }
  175.     }
  176. }
  177.  
  178. void commandRotateBox()
  179. {
  180.     commandRotate_sub(AREA_BOX);
  181. }
  182.  
  183. void commandRotatePoly()
  184. {
  185.     commandRotate_sub(AREA_POLYGON);
  186. }
  187.